package com.longma.server.security;

import com.longma.server.constant.enums.ResponseCode;
import com.longma.server.pojo.UserResponseEntity;
import com.longma.server.service.impl.JwtUserDetailsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


/**
 * @author HIBO
 * @Description  token身份认证过滤器
 */
@Configuration
@Slf4j
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    private static final Integer ADMIN_TYPE = 1;
    private static final String LOGIN_URI = "/api/login";
    private static final String USER_ADD_URI = "/api/user/add";
    private static final String USER_DEL_LIST_URI = "/api/user/dellist";

    @Autowired
    JwtUserDetailsService jwtUserDetailsService;

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        httpServletResponse.setContentType("application/json;charset=utf-8");
        //获取请求头authorization信息
        String requestHeader = httpServletRequest.getHeader(JwtTokenUtil.AUTH_HEADER_KEY);

        if (LOGIN_URI.equals(httpServletRequest.getRequestURI())){
            requestHeader = null;
        }

        String loginName;
        String authToken;
        Integer type;
        //有token时验证token
        if (requestHeader != null && requestHeader.startsWith("Bearer ")) {
            authToken = requestHeader.substring(7);
            loginName = JwtTokenUtil.getUsernameFromToken(authToken);
            type = JwtTokenUtil.getUserTypeFromToken(authToken);

            if (!ADMIN_TYPE.equals(type) && (USER_ADD_URI.equals(httpServletRequest.getRequestURI())) && (USER_DEL_LIST_URI.equals(httpServletRequest.getRequestURI()))){
                log.info("非管理员无法添加用户", loginName);
                UserResponseEntity responseEntity = UserResponseEntity.fail(ResponseCode.NO_PERMISSION);
                httpServletResponse.setStatus(HttpStatus.OK.value());
                httpServletResponse.setContentType("application/json;charset=utf-8");
                httpServletResponse.getWriter().write(responseEntity.toString());
                return;
            }

            if (loginName != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                // 加载用户信息  并校验用户合法性，失败抛出异常
                UserDetails userDetails = jwtUserDetailsService.loadUserByUsername(loginName);

                //验证token有效性 用户名是否正确、token是否过期
                if (JwtTokenUtil.validateToken(authToken, userDetails.getUsername())) {
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }
        }
        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }

}
